package com.okaixz.client.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.okaixz.client.mapper.ShareInfoMapper;
import com.okaixz.client.model.domain.ShareInfo;
import com.okaixz.client.model.domain.TaskInfo;
import com.okaixz.client.model.domain.User;
import com.okaixz.client.model.dto.ShareInfoDto;
import com.okaixz.client.model.dto.UserDto;
import com.okaixz.client.service.IShareInfoService;
import com.okaixz.client.service.ITaskInfoService;
import com.okaixz.client.service.ITokenService;
import com.okaixz.client.service.IUserService;
import com.okaixz.common.client.exception.BusinessException;
import com.okaixz.common.client.exception.CommonErrorCode;
import com.okaixz.common.constant.CommonConstants;
import com.okaixz.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cdz
 * @since 2024-11-10
 */
@Service
@Slf4j
public class ShareInfoServiceImpl extends ServiceImpl<ShareInfoMapper, ShareInfo> implements IShareInfoService {
    @Autowired
    private IUserService userService;
    @Autowired
    private ITaskInfoService taskInfoService;
    @Autowired
    private ITokenService tokenService;


    @Override
    public ShareInfo saveShareInfo(User user, String shareUserId) {
        ShareInfo shareInfo = new ShareInfo();
        shareInfo.setUserId(shareUserId);
        shareInfo.setCreateTime(LocalDateTime.now());
        shareInfo.setInviteUserId(user.getUserId());
        shareInfo.setInviteUserImage(user.getImage());
        shareInfo.setInviteUserNickName(user.getNickName());
        shareInfo.setType(0);
        shareInfo.setStatus(0);
        save(shareInfo);
        return shareInfo;
    }

    @Override
    public List<ShareInfoDto> getListByUserId(String userId) {
        List<ShareInfo> list = lambdaQuery()
                .eq(ShareInfo::getUserId, userId)
                .eq(ShareInfo::getStatus, CommonConstants.STATUS_ENABLE)
                .list();
        if (list == null) {
            return null;
        }
        //将list转为dto
        List<ShareInfoDto> dtoList = list.stream().map(shareInfo -> {
            ShareInfoDto dto = new ShareInfoDto();
            BeanUtils.copyProperties(shareInfo, dto);
            return dto;
        }).collect(Collectors.toList());

        return dtoList;
    }
    /**
     * 提交邀请码
     * @param userId
     * @param code
     * @return
     */
    @Override
    public UserDto submit(String userId, String code) {
        if (userId == null||  code == null) {
            throw new BusinessException(CommonErrorCode.PARAM_ERROR);
        }


        boolean isActiveCode = StringUtils.containsABC(code);//是否是活动码
        if (isActiveCode) {
            return null;
        }

        if(userId.equals(code)){
            throw new BusinessException(CommonErrorCode.SHARE_ERROR_CANNOT_SHARE_TO_YOURSELF);
        }


        User user = userService.getUserFormRedisOrDb(userId);
        if (user == null) {
            throw new BusinessException(CommonErrorCode.USER_NOT_EXIST);
        }
        LocalDateTime createdTime = user.getCreatedTime();
//        log.info("用户创建时间：{}",createdTime.plusDays(7));
//        log.info("当前时间：{}",LocalDateTime.now());
        if (createdTime.plusDays(7).isBefore(LocalDateTime.now())) {
            //判断创建时间距离今天是否超过7天
            throw new BusinessException(CommonErrorCode.SHARE_ERROR_USER_CREATETIME_IS_AFTER_7DAYS);
        }
        User shareUser = userService.getUserByUserIdAndClientName(user.getClientName(),code);//获取邀请码所属用户
        if (shareUser == null) {
            throw new BusinessException(CommonErrorCode.SHARE_ERROR_SHARE_CODE_NOT_EXIST);
        }

        //判断是否已经绑定过
        ShareInfo shareInfo = getShareInfoByInviteUserId(userId);
        if(shareInfo!=null){
            throw new BusinessException(CommonErrorCode.SHARE_ERROR_USER_ALREADY_BIND);
        }
        ShareInfo data=new ShareInfo();
        data.setUserId(shareUser.getUserId());
        data.setInviteUserId(userId);
        data.setInviteUserNickName(user.getNickName());
        data.setInviteUserImage(user.getImage());
        data.setClientName(user.getClientName());
        data.setStatus(CommonConstants.STATUS_ENABLE);
        data.setCreateTime(LocalDateTime.now());

        //保存邀请信息
        boolean result = save(data);
        if (result) {
            TaskInfo taskInfo = taskInfoService.getEnableTaskInfoByClientNameAndType(CommonConstants.TASK_TYPE_YAOQING,  user.getClientName());
            if (taskInfo == null) {
                throw new BusinessException(CommonErrorCode.OP_FAIL);
            }
            UserDto updateUser=new UserDto();
            updateUser.setUserId(userId);
            Integer remainTimes = user.getRemainTimes();
            if (remainTimes == null) {
                remainTimes=0;
            }
            Integer flag = taskInfo.getFlag();

            UserDto userDto=null;
            List<ShareInfoDto> listByUserId = getListByUserId(shareUser.getUserId());
            switch (flag) {
                case CommonConstants.TASK_FLAG_0://增加试用次数
                    //给提交邀请码的用户发放试用次数
                    updateUser.setRemainTimes(remainTimes+taskInfo.getPlusValue());
                    userDto = userService.updateUserInfoByUserId(updateUser);

                    //给邀请码所属用户发放试用次数
                    if (listByUserId != null&&listByUserId.size()!=0) {
                        int size = listByUserId.size()%10;//可能有多轮，每轮10个
                        taskInfo=null;
                        if(size==2){
                            taskInfo=taskInfoService.getEnableTaskInfoByIdAndClientName(15,  user.getClientName());
                        }else if(size==5){
                            taskInfo=taskInfoService.getEnableTaskInfoByIdAndClientName(16,  user.getClientName());
                        }else if (size==0){
                            //满10人
                            taskInfo=taskInfoService.getEnableTaskInfoByIdAndClientName(17,  user.getClientName());
                        }
                        if (taskInfo != null) {
                            shareUser.setRemainTimes(shareUser.getRemainTimes()+taskInfo.getPlusValue());
                            userService.updateUserByUserId(shareUser);
                        }
                    }
                    break;
                case CommonConstants.TASK_FLAG_1://增加会员天数
                    //给提交邀请码的用户发放会员天数;
                    userDto = userService.updateVipExpireTime(taskInfo.getPlusValue(),userId);

                    if (listByUserId != null&&listByUserId.size()!=0) {
                        //给邀请码所属用户发放试用次数
                        int size = listByUserId.size()%10;//可能有多轮，每轮10个
                        taskInfo=null;
                        if(size==2){
                            taskInfo=taskInfoService.getEnableTaskInfoByClientNameAndType(CommonConstants.TASK_TYPE_YAOQING2,  user.getClientName());
                        }else if(size==5){
                            taskInfo=taskInfoService.getEnableTaskInfoByClientNameAndType(CommonConstants.TASK_TYPE_YAOQING5, user.getClientName());
                        }else if (size==0){
                            //满10人
                            taskInfo=taskInfoService.getEnableTaskInfoByClientNameAndType(CommonConstants.TASK_TYPE_YAOQING10, user.getClientName());
                        }
                        if (taskInfo != null) {
                            userService.updateVipExpireTime(taskInfo.getPlusValue(),shareUser.getUserId());
                        }
                    }
                    break;
                case 2:

                    break;
            }

            return userDto;
        }else {
            throw new BusinessException(CommonErrorCode.OP_FAIL);
        }

    }

    @Override
    public ShareInfo getShareInfoByInviteUserId(String userId) {
        if (userId == null) {
            return null;
        }
        return lambdaQuery()
                .eq(ShareInfo::getInviteUserId, userId)
                .one();
    }
}
